import os
import sys
import glob
from Cookie import Cookie, SimpleCookie, CookieError 
from DAO import DAO
from Output import output
import random
import time

class playlistHandler:
    MSG501 = "Status: 501 Not Implemented\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n"
    MSG404 = "Status: 404 Not Found\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n"
    MSG0LEN = "Content-Length: 0\r\nContent-Type: text/plain\r\n\r\n"
    defaultuser = "enrique"
    
    "initialize playlist handler"
    def __init__(self, mode):
        self.m_Dao = DAO("users.db")
        self.output = output(mode)
        
    def CreatePlaylist(self, name, existingCookie):
        if(existingCookie is None):
            self.output.append("CreatePlaylist: Bad Cookie", True)
            return -1
        
        userName = existingCookie["user"].value
        accessedTime = int(name.split("-")[1])
        
        if self.m_Dao.userExists(userName) is False:
            self.m_Dao.insertData(userName, accessedTime)
            
        # if name contains 01/02 etc
        # I think: above check is for: if it is a movie file, only then insertAD
        if self.IsMovieFile(name) is True:
            lastAccessedTime = self.m_Dao.GetLastAccessedTime(userName)
            time_difference = accessedTime - lastAccessedTime
            
            if(time_difference > 20):
                #update LastAccessedTime in DB
                self.m_Dao.UpdateLastAccessedTime(userName, accessedTime)
                
                #insert AD
                self.InsertAd(userName)
        
    def InsertAd(self, username):
        #insert ad
        contentType = "application/vnd.apple.mpegurl"
        baseDirectory= "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/envivio22a/ads/ch1/"
        adName = ""
        
        if(username == "shafiq"):
            adName="bipbop3_6.m3u8"
        elif(username == "enrique"):
            adName="bipbop3_6.m3u8"
        else:
            adName="bipbop3_6.m3u8"
            
        adName = baseDirectory + adName;
        self.output.append("Content-Length: %d\r\nContent-Type: %s\r\n\r\n" % os.path.getsize(adName), contentType)
        self.writeFileToStdout(adName)
    
    def GetHttpCookie(self):
        try:
            return SimpleCookie(os.environ["HTTP_COOKIE"])
        except:
            self.output.append("Something is wrong with the cookie ", True)
            
            cookie = SimpleCookie()
            cookie["user"] = self.defaultuser
            
            os.environ["HTTP_COOKIE"] = str(cookie)
            return None
        
    def IsMovieFile(self, name):
        file1 = "01."
        file2 = "02."
        file3 = "03."
        file5 = ".ts"
        file6 = ".key"
        if((name.find(file1) != -1) or (name.find(file2) != -1) or (name.find(file3) != -1) or (name.endswith(file5))):
            return True
        return False
    
    def HandleRequest(self, method, name):        
        self.output.clear()
        contentType = self.GetContentType(name)
        
        if method == "MKCOL":
            self.HandleMKCOL(name)
            
        elif name.endswith("index.m3u8")  or name.endswith(".ts") or name.endswith(".key") or (name.endswith(".jpg") and not name.endswith("thumb.jpg")):
            self.HandleIndexM3u8(method, name, contentType)
            
        elif name.endswith(".m3u8") or name.endswith("thumb.jpg"):
            self.HandleM3u8(method, name, contentType)
            
        elif method == "DELETE" and os.path.isdir(name):
            self.HandleDelete(name)
        else:
            self.output.append(self.MSG501)            
        
        if(self.output.mode == output.LOGMODE):
            return self.output
        
    def GetContentType(self, name):
        contentType=''
        if name.endswith(".m3u8"):
            contentType = "application/vnd.apple.mpegurl"
        elif name.endswith(".ts"):
            contentType = "video/mpeg"
        elif name.endswith(".jpg"):
            contentType = "image/jpeg"
        elif name.endswith(".key"):
            contentType = "application/binary"
            
        return contentType
        
    def writeFileToStdout(self, name):
        f = open(name, "rb")
        while True:
            next = f.read(4096)
            if not next:
                break
            self.output.append(next)
        f.close()
        
    def GetModifiedTime(self, name):
        try:
            return os.path.getmtime(name)
        except:
            self.output.append("Error in GetModifiedTime: file doesn't exist or is inaccessible", True)
            return 0
                
    def HandleIndexM3u8(self, method, name, contentType):
        
        if method == "GET":
                self.output.append("Content-Length: %d\r\nContent-Type: %s\r\n\r\n" % (os.path.getsize(name), contentType))
                self.writeFileToStdout(name)
        elif method == "PUT":
                self.writeStdinToFile(name)
                self.output.append(self.MSG0LEN)
        elif method == "DELETE":
            os.remove(name)
            self.output.append(self.MSG0LEN)
        else:
            self.output.append(self.MSG501)
        
    def HandleM3u8(self, method, name, contentType):
        if method == "GET":                       
            names = glob.glob("%s-*" % name)
            if len(names) == 0:
                self.output.append("Error: HandleRequest:: Invalid names in glob glob for name\n", True)
                self.output.append(self.MSG404)
            else:
                (date, name) = max((self.GetModifiedTime(name), name) for name in names)
                cookie = self.GetHttpCookie()
            
                if(cookie is not None):
                    self.CreatePlaylist(name, cookie)
                #else:
                self.output.append("Content-Length: %d\r\nContent-Type: %s\r\n\r\n" % (os.path.getsize(name), contentType))
                self.writeFileToStdout(name)
        if method == "PUT":
            names = glob.glob("%s-*" % name)
            name = "%s-%d-%d" % (name, time.time(), random.randint(100000, 999999))
            self.writeStdinToFile(name)
            threshold = self.GetModifiedTime(name) - 60
            while len(names) > 2:
                (date, name) = min((self.GetModifiedTime(name), name) for name in names)
                if date > threshold:
                    break
                try:
                    os.remove(name)
                except:
                    pass
                names.remove(name)
            self.output.append("Content-Length: 0\r\n\r\n")

    def HandleDelete(self, name):
        os.rmdir(name)
        self.output.append(self.MSG0LEN)

    def HandleMKCOL(self, name):
        os.mkdir(os.path.dirname(name))
        self.output.append(self.MSG0LEN)
                            
    def writeStdinToFile(self, name):
        fileHandle = open(name, "wb")
        while True:
            next = sys.stdin.read(4096)
            if not next:
                break
            fileHandle.write(next)
        fileHandle.close()